// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "LyraNumberPopComponent.h"

#include "LyraNumberPopComponent_MeshText.generated.h"

class ULyraDamagePopStyle;
class UMaterialInstanceDynamic;
class UObject;
class UStaticMesh;
class UStaticMeshComponent;

USTRUCT()
struct FPooledNumberPopComponentList
{
	GENERATED_BODY()

	UPROPERTY(transient)
	TArray<TObjectPtr<UStaticMeshComponent>> Components; // 组件数组
};

USTRUCT()
struct FLiveNumberPopEntry
{
	GENERATED_BODY()

	/** The component that is currently live */
	UPROPERTY(transient)
	TObjectPtr<UStaticMeshComponent> Component = nullptr; // 当前活跃的组件

	/** The pool this component will go into when released */
	FPooledNumberPopComponentList* Pool = nullptr; // 组件释放时将返回的池

	/** The world time that this component will be released to the pool */
	float ReleaseTime = 0.0f; // 组件释放到池的世界时间

	FLiveNumberPopEntry()
	{}

	FLiveNumberPopEntry(UStaticMeshComponent* InComponent, FPooledNumberPopComponentList* InPool, float InReleaseTime)
		: Component(InComponent), Pool(InPool), ReleaseTime(InReleaseTime)
	{}
};

/** Struct that holds the info for a new damage number */
/**
 * 保存新伤害数字信息的结构体
 */
struct FTempNumberPopInfo
{
	UStaticMeshComponent* StaticMeshComponent = nullptr; // 静态网格组件

	TArray<UMaterialInstanceDynamic*> MeshMIDs; // 网格材质实例动态数组

	TArray<int32> DamageNumberArray; // 伤害数字数组
};




UCLASS(Blueprintable)
class ULyraNumberPopComponent_MeshText : public ULyraNumberPopComponent
{
	GENERATED_BODY()

public:

	ULyraNumberPopComponent_MeshText(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

	//~ULyraNumberPopComponent interface
	virtual void AddNumberPop(const FLyraNumberPopRequest& NewRequest) override;
	//~End of ULyraNumberPopComponent interface

protected:
	/**
	 * 设置材质参数
	 */
	void SetMaterialParameters(const FLyraNumberPopRequest& Request, FTempNumberPopInfo& NewDamageNumberInfo, const FTransform& CameraTransform, const FVector& NumberLocation);

	/**
	 * 确定颜色
	 */
	FLinearColor DetermineColor(const FLyraNumberPopRequest& Request) const;
	/**
	 * 确定静态网格
	 */
	UStaticMesh* DetermineStaticMesh(const FLyraNumberPopRequest& Request) const;


	/** Releases components back to the pool that have exceeded their lifespan */
	/**
	 * 将超过生命周期的组件释放回池
	 */
	void ReleaseNextComponents();

	/** Style patterns to attempt to apply to the incoming number pops */
	UPROPERTY(EditDefaultsOnly, Category="Number Pop|Style")
	TArray<TObjectPtr<ULyraDamagePopStyle>> Styles; // 尝试应用于传入数字弹出的样式模式

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Number Pop|Style")
	float ComponentLifespan; // 组件生命周期

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Style")
	float DistanceFromCameraBeforeDoublingSize; // 距离相机多远时尺寸加倍
	
	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Style")
	float CriticalHitSizeMultiplier; // 暴击尺寸乘数

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Font")
	float FontXSize; // 字体 X 尺寸

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Font")
	float FontYSize; // 字体 Y 尺寸

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Font")
	float SpacingPercentageForOnes; // 数字1的间距百分比

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Style")
	float NumberOfNumberRotations; // 数字旋转次数

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	FName SignDigitParameterName; // 符号数字参数名称

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	FName ColorParameterName; // 颜色参数名称

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	FName AnimationLifespanParameterName; // 动画生命周期参数名称

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	FName IsCriticalHitParameterName; // 是否为暴击参数名称

	/** Damage numbers by default are given a depth close to the camera in the material to make sure they are never occluded. This can be toggled off here, should only be 0/1. */
	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	FName MoveToCameraParameterName; // 移动到相机参数名称（默认伤害数字在材质中被赋予靠近相机的深度以确保它们永远不会被遮挡。可以在此处关闭，应为0/1。）

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	TArray<FName> PositionParameterNames; // 位置参数名称数组

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	TArray<FName> ScaleRotationAngleParameterNames; // 缩放旋转角度参数名称数组

	UPROPERTY(EditDefaultsOnly, Category = "Number Pop|Material Bindings")
	TArray<FName> DurationParameterNames; // 持续时间参数名称数组

	UPROPERTY(Transient)
	TMap<TObjectPtr<UStaticMesh>, FPooledNumberPopComponentList> PooledComponentMap; // 池化组件映射

	UPROPERTY(transient)
	TArray<FLiveNumberPopEntry> LiveComponents; // 活跃组件数组

	FTimerHandle ReleaseTimerHandle; // 释放计时器句柄
};